import ch.quantasy.tinkerforge.tinker.TinkerManager;
import ch.quantasy.tinkerforge.tinker.TinkerforgeDevice;

import com.tinkerforge.BrickletAmbientLight;
import com.tinkerforge.BrickletAmbientLight.IlluminanceListener;
import com.tinkerforge.BrickletDistanceIR;
import com.tinkerforge.BrickletDistanceIR.DistanceListener;
import com.tinkerforge.BrickletHumidity;
import com.tinkerforge.BrickletHumidity.HumidityListener;
import com.tinkerforge.BrickletTemperatureIR;
import com.tinkerforge.BrickletTemperatureIR.AmbientTemperatureListener;
import com.tinkerforge.BrickletTemperatureIR.ObjectTemperatureListener;
import com.tinkerforge.Device;
import com.tinkerforge.TinkerforgeException;

/**
 * This class represents the wireless sensor-stack, which is placed within the
 * fridge. <br/>
 * It assumes that the sensor-stack is connected as a client on the current
 * wlan. <br/>
 * It assumes that the sensor-stack can be accessed by the server-name
 * <i>'fridge-sensor'</i>
 * 
 * If you cannot reach it, check the wlan-state of the wlan-brick by using
 * brickv.
 * 
 * @author reto
 * 
 */
public class FridgeSensor extends TinkerManager {
	private final ObjectTemperatureListener objectTemperatureListener;
	private final AmbientTemperatureListener ambientTemperatureListener;
	private final HumidityListener humidityListener;
	private final DistanceListener distanceListener;
	private final IlluminanceListener illuminanceListener;

	/**
	 * The FridgeSensor expects the listed set of Listeners which it will manage
	 * even under rough conditions
	 * 
	 * @param objectTemperatureListener
	 * @param ambientTemperatureListener
	 * @param humidityListener
	 * @param distanceListener
	 * @param illuminanceListener
	 */
	public FridgeSensor(String fridgeSensorHostName,
			final ObjectTemperatureListener objectTemperatureListener,
			final AmbientTemperatureListener ambientTemperatureListener,
			final HumidityListener humidityListener,
			final DistanceListener distanceListener,
			final IlluminanceListener illuminanceListener) {
		super(fridgeSensorHostName);
		this.objectTemperatureListener = objectTemperatureListener;
		this.ambientTemperatureListener = ambientTemperatureListener;
		this.humidityListener = humidityListener;
		this.distanceListener = distanceListener;
		this.illuminanceListener = illuminanceListener;
	}

	@Override
	public void connected() {
		System.out.println("Fridge-Sensor connected");
	}

	@Override
	public void disconnected() {
		System.out.println("Fridge-Sensor disconnected");
	}

	@Override
	public void deviceConnected(final Device device) {
		this.setListener(device);
	}

	@Override
	public void deviceReConnected(final Device device) {
		this.setListener(device);
	}

	@Override
	public void deviceDisconnected(final Device device) {
		if (TinkerforgeDevice.getDevice(device) == TinkerforgeDevice.AmbientLight) {
			((BrickletAmbientLight) device)
					.removeIlluminanceListener(this.illuminanceListener);
		}
		if (TinkerforgeDevice.getDevice(device) == TinkerforgeDevice.DistanceIR) {
			((BrickletDistanceIR) device)
					.removeDistanceListener(this.distanceListener);
		}

		if (TinkerforgeDevice.getDevice(device) == TinkerforgeDevice.Humidity) {
			((BrickletHumidity) device)
					.removeHumidityListener(this.humidityListener);
		}
		if (TinkerforgeDevice.getDevice(device) == TinkerforgeDevice.TemperatureIR) {
			((BrickletTemperatureIR) device)
					.removeObjectTemperatureListener(this.objectTemperatureListener);
			((BrickletTemperatureIR) device)
					.removeAmbientTemperatureListener(this.ambientTemperatureListener);
		}
	}

	private void setListener(final Device device) {

		if (TinkerforgeDevice.getDevice(device) == TinkerforgeDevice.AmbientLight) {
			final BrickletAmbientLight ambient = (BrickletAmbientLight) device;
			ambient.addIlluminanceListener(this.illuminanceListener);
			try {
				ambient.setIlluminanceCallbackPeriod(500);
			} catch (final TinkerforgeException ex) {
			}
		}
		if (TinkerforgeDevice.getDevice(device) == TinkerforgeDevice.DistanceIR) {
			final BrickletDistanceIR distance = (BrickletDistanceIR) device;
			distance.addDistanceListener(this.distanceListener);
			try {
				distance.setDistanceCallbackPeriod(500);
			} catch (final TinkerforgeException ex) {
			}
		}

		if (TinkerforgeDevice.getDevice(device) == TinkerforgeDevice.Humidity) {
			final BrickletHumidity humidity = (BrickletHumidity) device;
			humidity.addHumidityListener(this.humidityListener);
			try {
				humidity.setHumidityCallbackPeriod(500);
			} catch (final TinkerforgeException ex) {
			}
		}
		if (TinkerforgeDevice.getDevice(device) == TinkerforgeDevice.TemperatureIR) {
			final BrickletTemperatureIR tempIR = (BrickletTemperatureIR) device;
			tempIR.addObjectTemperatureListener(this.objectTemperatureListener);
			tempIR.addAmbientTemperatureListener(this.ambientTemperatureListener);

			try {
				tempIR.setObjectTemperatureCallbackPeriod(500);
				tempIR.setAmbientTemperatureCallbackPeriod(500);
			} catch (final TinkerforgeException ex) {
			}

		}
	}

}
